﻿namespace NTLib.Core.Configuration
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    /// <summary>
    /// Collection that contain all the configuration value.
    /// </summary>
    /// <seealso cref="System.Collections.Generic.Dictionary{System.String, System.Collections.Generic.List{NTLib.Core.Configuration.ConfigValue}}" />
    public sealed class ConfigurationCollection : Dictionary<string, List<ConfigValue>>
    {
        #region Ctor

        /// <summary>
        /// Initializes a new instance of the <see cref="ConfigurationCollection"/> class.
        /// </summary>
        public ConfigurationCollection()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ConfigurationCollection"/> class.
        /// </summary>
        /// <param name="values">The values.</param>
        public ConfigurationCollection(IEnumerable<ConfigValue> values)
        {
            AddRange(values);
        }

        #endregion

        #region Methods

        /// <summary>
        /// Adds the specified value.
        /// </summary>
        public void Add(ConfigValue value)
        {
            if (value == null)
                throw new ArgumentNullException(nameof(value));

            List<ConfigValue> configs = null;

            if (this.TryGetValue(value.ConfigKey, out configs))
            {
                configs.Add(value);
            }
            else
            {
                this.Add(value.ConfigKey, new List<ConfigValue>() { value });
            }
        }

        /// <summary>
        /// Adds multiple data in the configuration collection.
        /// </summary>
        /// <param name="values">The values.</param>
        public void AddRange(IEnumerable<ConfigValue> values)
        {
            var groups = (from v in values
                          group v by v.ConfigKey);

            foreach (var grp in groups)
            {
                if (grp.Count() > 1)
                {
                    List<ConfigValue> configs = null;

                    if (this.TryGetValue(grp.Key, out configs))
                    {
                        configs.AddRange(grp);
                    }
                    else
                    {
                        this.Add(grp.Key, new List<ConfigValue>(grp));
                    }
                }
                else
                {
                    this.Add(grp.First());
                }
            }
        }

        #endregion
    }
}
